package Distribuciones;

import ec.util.MersenneTwisterFast;
import entidad.FactoryDistribucion.DISTRIBUCION_NOMBRES;

public class Gamma implements Distribucion{
    private double alfa;
    private double beta;
    MersenneTwisterFast prng;
    public static final DISTRIBUCION_NOMBRES nombre = DISTRIBUCION_NOMBRES.GAMMA;
    public static final String[] parametros = {"alfa","beta"};
    public static final String[] tipoParametros = {"double","double"};
    
    public Gamma(double a, double b, MersenneTwisterFast prng){
        alfa=a;
        beta=1d/b;
        this.prng = prng;
    }

    @Override
    public String[] getParametros() {
        return parametros;
    }

    @Override
    public String[] getTipoParametros() {
        return tipoParametros;
    }

    @Override
    public double generar( double u){
        double a=1d/Math.sqrt(2*alfa-1);
        double b=alfa-Math.log(4);
        double q=alfa+1d/a;
        double theta=4.5;
        double d=1+Math.log(theta);
        double u1=u;
        double u2=prng.nextDouble();
        double v=a*Math.log(u1/(1-u1));
        double y=alfa*Math.exp(v);
        double z=u1*u1*u2;
        double w=b+q*v-y;
        while(w+d-theta*z<0){
            if(w>=Math.log(z)){
                return y*beta;
            }else{
            u1=prng.nextDouble();
            u2=prng.nextDouble();
            v=a*Math.log(u1/(1-u1));
            y=alfa*Math.exp(v);
            z=u1*u1*u2;
            w=b+q*v-y;
            }
        }
        return y*beta;
    }

    public DISTRIBUCION_NOMBRES getNombre() {
    return nombre;
    }

    @Override
    public double calcularMedia() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
